/**
 * 1.then返回Promise，参数方法的return会向后传（且支持普通数据和Promise）
 * 2.catch返回Promise，参数方法的return会向后传（且支持普通数据和Promise）
 * 3.then和catch中的参数方法的return都会在下一轮的then和catch中的参数方法被接受
 * 4.返回普通数据或Promise.resolve()，会传到下一轮then
 * 5.返回Promise.reject(),会传到下一轮catch
 * 6.不管是成功还是失败，遇到finally时都会执行一下它的参数方法，不会对其他流程造成影响
 */

/**
 * 要实现的方法
 * 原型方法：resolve, reject, then, catch, finally
 * 实例方法：resolve, reject, all, race, allSettled
 */

const PENDING = "pending",
  FULFILLED = "fulfilled",
  REJECTED = "rejected";
const isFun = (handle) => typeof handle === "function";
class MyPromise {
  constructor(handle) {
    if (!isFun(handle)) {
      throw new Error("Promise的参数必须是一个函数");
    }
    this.fulfilledQueues = [];
    this.rejectedQueues = [];
    this.status = PENDING;
    this.value = null;
    handle(this.resolve.bind(this), this.reject.bind(this));
  }
  resolve(value) {
    const run = () => {
      if (this.status !== PENDING) {
        return;
      }
      this.status = FULFILLED;
      this.value = value;
      let cb = null;
      while ((cb = this.fulfilledQueues.shift())) {
        cb(value);
      }
    };
    setTimeout(run, 0);
  }
  reject(value) {
    const run = () => {
      if (this.status !== PENDING) {
        return;
      }
      this.status = FULFILLED;
      this.value = value;
      let cb = null;
      while ((cb = this.rejectedQueues.shift())) {
        cb(value);
      }
    };
    setTimeout(run, 0);
  }
  then(onFulfilled, onRejected) {
    return new MyPromise((nextFulfilled, nextRejected) => {
      const waitFulfilled = (value) => {
        if (isFun(onFulfilled)) {
          const res = onFulfilled(value);
          if (res instanceof MyPromise) {
            res.then(nextFulfilled, nextRejected);
          } else {
            nextFulfilled(res);
          }
        }
      };
      const waitRejected = (value) => {
        if (isFun(onRejected)) {
          const res = onRejected(value);
          if (res instanceof MyPromise) {
            res.then(nextFulfilled, nextRejected);
          } else {
            nextRejected(res);
          }
        }
      };
      switch (this.status) {
        case PENDING:
          this.fulfilledQueues.push(waitFulfilled);
          this.rejectedQueues.push(waitRejected);
          break;
        case FULFILLED:
          waitFulfilled(this.value);
          break;
        case REJECTED:
          waitRejected(this.value);
          break;
        default:
          break;
      }
    });
  }
  catch(onRejected) {
    return this.then(null, onRejected);
  }
  finally(fn) {
    return this.then(
      (value) => {
        fn("111");
        return value;
      },
      (reason) => {
        throw reason;
      }
    );
  }
  static resolve(res) {}
  static reject(res) {}
  static all(arr) {}
  static race(arr) {}
  static allSettled(arr) {}
}

// function foo() {
//     return new MyPromise((resolve, reject) => {
//         resolve('你是正确的');
//         // reject('你是错误的')
//     })
// }

// foo().then(res => {
//     console.log(res);
//     // then的return会向后传（且支持普通数据和Promise）
//     // return '你又对了';
//     return new MyPromise((resolve, reject) => {
//         resolve('你又对了')
//     })
// }, (err) => {
//     console.log(err)
// }).catch(err => {
//     console.log(err);
//     // catch的return不会向后传
//     return '你又错了';
//     return Promise.reject('你又错了')
// }).finally((res) => {
//     console.log(res);
// }).then(res => {
//     console.log(res)
// }).catch(err => {
//     //  console.log(err);
// })

// Promise.reject("test")
//   .catch((data) => console.log(data))
//   .then((data) => console.log(data));

var date = new Date();

console.log(1, new Date() - date);

setTimeout(() => {
  console.log(2, new Date() - date);
}, 500);

// 传进去的是函数log的执行结果，所有事同步执行
Promise.resolve().then(console.log(3, new Date() - date));

while (new Date() - date < 1000) {}

console.log(4, new Date() - date);
